import { Injectable } from '@angular/core';
import { BackgroundManager, Options, Shape } from '@antv/x6';
import { GridManager } from '@antv/x6/lib/graph/grid';
import { MouseWheel } from '@antv/x6/lib/graph/mousewheel';
import { PanningManager } from '@antv/x6/lib/graph/panning';


@Injectable()
export class GraphConfigService {

  constructor() { }

  getGraphOptions(settings: Partial<OptionSetting>): Options.Manual {
    const options: Options.Manual = {};

    if (settings.grid) {
      options.grid = getGrid();
    }
    if (settings.background) {
      options.background = getBackground();
    }

    if (settings.panning) {
      options.panning = getPanning();
    }
    if (settings.mousewheel) {
      options.mousewheel = getMousewheel();
    }
    if (settings.connecting) {
      options.connecting = getConnecting();
    }
    if (settings.highlighting) {
      options.highlighting = getHighlighting();
    }
    if (settings.embedding) {
      options.embedding = getEmbedding();
    }

    return options;
  }

  // getPluginSetting(): Partial<PluginSetting> {
  //   return {

  //   };
  // }

}
function getGrid(): number | boolean | (Partial<GridManager.CommonOptions> & GridManager.DrawGridOptions) | undefined {
  return {
    visible: true,
    type: 'doubleMesh',
    args: [
      {
        color: '#eee', // 主网格线颜色
        thickness: 1, // 主网格线宽度
      },
      {
        color: '#ddd', // 次网格线颜色
        thickness: 1, // 次网格线宽度
        factor: 5, // 主次网格线间隔
      },
    ],
  };
}

function getBackground(): false | BackgroundManager.Options | undefined {
  return {
    color: '#F2F7FA',
  };
}
function getPanning(): boolean | Partial<PanningManager.Options> | undefined {
  return {
    enabled: true,
    eventTypes: ['leftMouseDown'],
    modifiers: ["ctrl"]
  };
}
function getMousewheel(): boolean | Partial<MouseWheel.Options> | undefined {
  return {
    enabled: true,
    zoomAtMousePosition: true,
    modifiers: ['ctrl'],
    minScale: 0.5,
    maxScale: 3,
  };
}
function getConnecting(): Partial<Options.Connecting> | undefined {
  return {
    router: 'metro',
    connector: {
      name: 'rounded',
      args: {
        radius: 16,
      },
    },
    anchor: "center",
    connectionPoint: 'anchor',
    allowBlank: false,
    allowNode: false,
    allowEdge: false,
    allowMulti: true,
    allowPort: true,
    snap: {
      radius: 20,
      anchor: "center"
    },
    createEdge() {
      return new Shape.Edge({
        attrs: {
          line: {
            stroke: '#A2B1C3',
            strokeWidth: 2,
            targetMarker: {
              name: 'block',
              width: 12,
              height: 8,
            },
          },
        },
        zIndex: 0,
      });
    },
    validateMagnet({ magnet }) {
      // 节点上方的连接桩无法创建连线
      return magnet.getAttribute('port-group') !== 'in';
    },
    validateConnection({
      sourceCell,
      targetCell,
      sourceMagnet,
      targetMagnet,
    }) {
      // 不能连接自身
      if (sourceCell === targetCell) {
        return false;
      }

      // 只能从 bottom 连接桩开始连接，连接到 top 连接桩
      if (
        !sourceMagnet ||
        sourceMagnet.getAttribute('port-group') === 'in'
      ) {
        return false;
      }
      if (
        !targetMagnet ||
        targetMagnet.getAttribute('port-group') !== 'in'
      ) {
        return false;
      }

      // 不能重复连线
      const edges = this.getEdges();
      const portId = targetMagnet.getAttribute('port');
      if (edges.find((edge) => edge.getTargetPortId() === portId)) {
        return false;
      }

      return true;
    },
  };
}
function getHighlighting(): Partial<Options.Highlighting> | undefined {
  return {
    // 连接桩可以被连接时在连接桩外围围渲染一个包围框
    magnetAvailable: {
      name: 'stroke',
      args: {
        attrs: {
          fill: '#fff',
          stroke: '#A4DEB1',
          strokeWidth: 4,
        },
      },
    },
    // 连接桩吸附连线时在连接桩外围围渲染一个包围框
    magnetAdsorbed: {
      name: 'stroke',
      args: {
        attrs: {
          fill: '#fff',
          stroke: '#31d0c6',
          strokeWidth: 4,
        },
      },
    },

  };
}

function getEmbedding(): Partial<Options.Embedding> {
  return {
    enabled: true,
    findParent({ node }) {
      // 获取移动节点的包围盒
      const bbox = node.getBBox();
      const { category } = node.getData<{ category: string; }>();

      // 找到 data 中配置 { parent: true } 的节点，并且移动节点和找到的节点包围盒相交时，返回 true
      return this.getNodes().filter((node) => {
        if (category == "Srm" || category == "Pipline") {
          return false;
        }
        const data = node.getData<{ parent: boolean; }>();
        if (data && data.parent) {
          const targetBBox = node.getBBox();
          return bbox.isIntersectWithRect(targetBBox);
        }
        return false;
      });
    }
  };

}

export interface PluginSetting {
  transform: boolean;
  selecton: boolean;
  snapline: boolean;
  keyboard: boolean;
  clipboard: boolean;
  history: boolean;
  minimap: boolean;
  dnd: boolean;
  export: boolean;
}

export interface OptionSetting {
  grid: boolean;
  background: boolean;
  panning: boolean;
  mousewheel: boolean;
  connecting: boolean;
  highlighting: boolean;
  embedding: boolean;
}